/**
 * Copyright (c) 2011 Basil Shikin, VintageRadio Project
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.vintagephone.view.flat;

import java.util.List;

import org.vintagephone.R;
import org.vintagephone.model.Song;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Typeface;

/**
 * This class defines a single radio dial. 
 * 
 * @author Basil Shikin
 *
 */
class RadioScreen
{
    private static final int SONG_DISTANCE = 90;
    private static final int SONG_ANIMATION_STEP = 2;
    
    // Parent objects
    private final int m_screenNumber;
    private final RadioDialController m_controller;
    
    private final Bitmap m_background;
    private final Bitmap m_volumeSelector;
    
    private final int m_width;
    private final int m_height;
    private final Paint m_bitmapPaint;
    private final Paint m_screenTitleFgPaint;
    private final Paint m_screenTitleBgPaint;
    private final Paint m_songNamePaint;
    private final Paint m_detailsPaint;
    

    // State variables
    private int m_songNameYOffset;
    private int m_targetSongNameYOffset;
    private int m_songNameStepDirection;

    // Constants
    private final String m_noSongsString;
    private final String m_scanningString;

    public RadioScreen(int screenNumber, final RadioDialController radioDialController, final Context context) 
    {
        m_screenNumber = screenNumber;
        m_controller = radioDialController;
        
        m_background = BitmapFactory.decodeResource( context.getResources(), R.drawable.dial );
        m_width = m_background.getWidth();
        m_height = m_background.getHeight();
        
        m_volumeSelector = BitmapFactory.decodeResource( context.getResources(), R.drawable.selector );
        
        m_bitmapPaint = new Paint();
        m_bitmapPaint.setColor( Color.BLACK );
        m_bitmapPaint.setStyle( Style.FILL );
        m_bitmapPaint.setFilterBitmap( true );
        
        m_songNamePaint = new Paint();
        m_songNamePaint.setColor( Color.rgb( 68, 0, 0) );
        m_songNamePaint.setAntiAlias( true );
        m_songNamePaint.setTextSize( 24F );
        m_songNamePaint.setTypeface( Typeface.createFromAsset( context.getAssets(), "fonts/optima-bold.ttf" ) );
        
        m_screenTitleFgPaint = new Paint();
        m_screenTitleFgPaint.setColor( Color.rgb( 22, 22, 22) );
        m_screenTitleFgPaint.setAntiAlias( true );
        m_screenTitleFgPaint.setTextSize( 12.5F );
        m_screenTitleFgPaint.setTypeface( Typeface.createFromAsset( context.getAssets(), "fonts/optima-bold.ttf" ) );
        
        m_screenTitleBgPaint = new Paint();
        m_screenTitleBgPaint.setColor( Color.argb( 100, 255, 255, 255 ) );
        m_screenTitleBgPaint.setAntiAlias( true );
        m_screenTitleBgPaint.setTextSize( 12.5F );
        m_screenTitleBgPaint.setTypeface( Typeface.createFromAsset( context.getAssets(), "fonts/optima-bold.ttf" ) );
        
        m_detailsPaint = new Paint();
        m_detailsPaint.setColor( Color.rgb( 68, 0, 0) );
        m_detailsPaint.setTextSize( 18F );
        m_detailsPaint.setAntiAlias( true );
        m_detailsPaint.setTypeface( Typeface.createFromAsset( context.getAssets(), "fonts/optima-normal.ttf" ) );
        
        m_noSongsString  = context.getResources().getString( R.string.no_songs );
        m_scanningString = context.getResources().getString( R.string.scanning );
    }
    
    void draw(Canvas canvas)
    {
        canvas.drawBitmap( m_background, 0, 0, m_bitmapPaint );
        
        if ( m_controller.getIsOff() )
        {
            canvas.drawBitmap( m_volumeSelector, 20, 154, m_bitmapPaint );
        }
        else
        {
            final float xOffset = 55 + 235*(m_controller.getVolume()/100F);
            canvas.drawBitmap( m_volumeSelector, xOffset, 154, m_bitmapPaint );
        }
        canvas.save();
        
        canvas.clipRect( 0, 60, m_width - 20, m_height - 100);
        
        renderScreenText( canvas );
        
        canvas.restore();
        
        renderScreenTitle( canvas );
    }
    
    void showSong( int songNumber )
    {
        final int songOffset = calculateSongOffset( songNumber );

        if ( m_songNameYOffset == songOffset ) return;
        
        if ( Math.abs( songOffset - m_songNameYOffset ) < 4*SONG_DISTANCE )
        {
            if ( songOffset > m_songNameYOffset )
            {
                m_songNameStepDirection = SONG_ANIMATION_STEP;
            }
            else
            {
                m_songNameStepDirection = -SONG_ANIMATION_STEP;
            }
        }
        else
        {
            // Do not move more then four songs. 
            m_songNameYOffset = songOffset;
        }
        
        m_targetSongNameYOffset = songOffset;
    }

    int getWidth()
    {
        return m_width;
    }
    
    boolean prepareAnimationState()
    {
        boolean songNeedsRepaint = false;
        for ( int screen = 0; screen < RadioDialController.SCREEN_COUNT; screen +=1 )
        {
            if ( isMovingSongName( screen ) )
            {
                m_songNameYOffset += m_songNameStepDirection;
                
                songNeedsRepaint = true;
            }
            else
            {
                if ( m_songNameYOffset != m_targetSongNameYOffset )
                {
                    songNeedsRepaint = true;
                }
                
                m_songNameYOffset = m_targetSongNameYOffset;
            }
        }
        
        return  songNeedsRepaint;
    }
    
    private void renderScreenTitle(Canvas canvas) 
    {
        final String text = m_controller.getScreenTitle( m_screenNumber );
        
        final Rect rect = new Rect();
        m_screenTitleBgPaint.getTextBounds( text.toCharArray(), 0, text.length(), rect);

        final int fontX = (300 - rect.width() );
        final int fontY = 50;
        
        canvas.drawText( text, fontX, fontY + 1, m_screenTitleBgPaint);
        canvas.drawText( text, fontX, fontY, m_screenTitleFgPaint);
    }
    

    private void renderScreenText(Canvas canvas) 
    {
        final int fontX = 20;
        final int fontY = -m_songNameYOffset + 100;
        
        final List<Song> screenSongs = m_controller.getScreenSongs( m_screenNumber );
        
        if ( screenSongs != null && !screenSongs.isEmpty() )
        {
            for ( int i = 0; i < screenSongs.size(); i++ )
            {
                final Song song = screenSongs.get( i );
                final int offsetY = i*SONG_DISTANCE;
                
                renderSongAtFor( song, fontX, fontY + offsetY, canvas);
            }
        }
        else
        {
            canvas.drawText( m_noSongsString, fontX, fontY, m_songNamePaint);
        }
    }
    
    private void renderSongAtFor(Song song, int fontX, int fontY, Canvas canvas) 
    {
        if ( song.isScanned() )
        {
            canvas.drawText( song.getTrack(), fontX, fontY, m_songNamePaint);
            canvas.drawText( song.getArtist(), fontX, fontY + 24, m_detailsPaint);
        }
        else
        {
            canvas.drawText( m_scanningString, fontX, fontY, m_songNamePaint);
        }
    }


    private boolean isMovingSongName( int screen ) 
    {
        return Math.abs( m_targetSongNameYOffset - m_songNameYOffset ) > SONG_ANIMATION_STEP/2;
    }

    private int calculateSongOffset(int songNumber) 
    {
        return songNumber * SONG_DISTANCE;
    }
}
